/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.octopeer.core;

import java.io.File;
import java.io.StringReader;

import java.util.ArrayList;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import org.xml.sax.InputSource;

import net.octopeer.utilities.XMLTools;

/**
 *
 * @author andria
 */
public class Peer {
    private String networkID = "Octopeer";
    private PeerNode node;
    private ArrayList<Resource> resourceList;
    private ArrayList<Neighbor> neighborList;
    private ArrayList<Cache> cacheList;
    private ArrayList<String> requestIDList;
    public String message;
    
    public Peer() {
        this.resourceList = new ArrayList<Resource>();
        this.neighborList = new ArrayList<Neighbor>();
        this.cacheList = new ArrayList<Cache>();
        this.requestIDList = new ArrayList<String>();
    }
    
    public Peer(PeerNode node) {
        this.node =node;
        this.resourceList = new ArrayList<Resource>();
        this.neighborList = new ArrayList<Neighbor>();
        this.cacheList = new ArrayList<Cache>();
        this.requestIDList = new ArrayList<String>();
    }
    
    // Peer constructors with other parameters combinations
    
    public void setNode(PeerNode node) {
        this.node = node;
    }
    
    public PeerNode getNode() {
        return this.node;
    }
    
    public void setNetworkID(String networkID) {
        this.networkID = networkID;
    }
    
    public String getNetworkID() {
        return this.networkID;
    }
    
    public void setResourceList(ArrayList<Resource> resourceList) {
        this.resourceList = resourceList;
    }
    
    public ArrayList<Resource> getResourceList() {
        return this.resourceList;
    }
    
    public boolean addResource(Resource peerResource) {
        boolean success = false;
        
        int resourceIdx = findResourceIdx(peerResource);
        if (resourceIdx == -1) {
            this.resourceList.add(peerResource);
            success = true;
        }
        
        return success;
    }
    
    public boolean removeResource(Resource peerResource) {
        boolean success = false;
        
        int resourceIdx = findResourceIdx(peerResource);
        if (resourceIdx != -1) {
            this.resourceList.remove(peerResource);
            success = true;
        }
        
        return success;
    }
    
    public int findResourceIdx(Resource peerResource) {
        int peerResourceIdx = -1;
        int loop = 0;
        Resource tempResource = null;
        
        while (loop < this.resourceList.size()) {
            tempResource = (Resource) this.resourceList.get(loop);
            
            if (tempResource.getResourceID().equals(peerResource.getResourceID())) {
                peerResourceIdx = loop;
                break;
            }
            
            loop++;
        }
        
        return peerResourceIdx;
    }
    
    public int findResourceIdxByKeyword(String resType, String resKeyword) {
        int peerResourceIdx = -1;
        int loop = 0;
        Resource tempResource = null;
        
        while (loop < this.resourceList.size()) {
            tempResource = (Resource) this.resourceList.get(loop);
            
            if (((tempResource.getResourceType().equals(resType))) &&
                    (tempResource.getResourceDetail().indexOf(resKeyword) != -1)) {
                peerResourceIdx = loop;
                break;
            }
            
            loop++;
        }
        
        return peerResourceIdx;
    }
    
    public void setNeighborList(ArrayList<Neighbor> peerList) {
        this.neighborList = peerList;
    }
    
    public ArrayList<Neighbor> getNeighborList() {
        return this.neighborList;
    }
    
    public boolean addNeighborNode(PeerNode peerNeighborNode) {
        boolean success = false;
        
        int peerIdx = findNeighborNodeIdx(peerNeighborNode);
        if (peerIdx == -1) {
            Neighbor newNeighbor = new Neighbor(peerNeighborNode, 1);
            this.neighborList.add(newNeighbor);
            success = true;
        } else {
            this.neighborList.get(peerIdx).incRank();
            success = true;
        }
        
        return success;
    }
    
    public boolean removeNeighborNode(PeerNode peerNeighborNode) {
        boolean success = false;
        
        int peerIdx = findNeighborNodeIdx(peerNeighborNode);
        if (peerIdx != -1) {
            if (this.neighborList.get(peerIdx).getRank() == 1) {
                this.neighborList.remove(peerIdx);
                success = true;
            } else {
                this.neighborList.get(peerIdx).decRank();
                success = true;
            }
        }
        
        return success;
    }
    
    public int findNeighborNodeIdx(PeerNode peerNeighborNode) {
        int peerNeighborIdx = -1;
        int loop = 0;
        Neighbor tempNeighbor = null;
        PeerNode tempNode = null;
        
        while (loop < this.neighborList.size()) {
            tempNeighbor = (Neighbor) this.neighborList.get(loop);
            tempNode = tempNeighbor.getNode();
            
            if (tempNode.getNodeID().equals(peerNeighborNode.getNodeID())) {
                peerNeighborIdx = loop;
                break;
            }
            
            loop++;
        }
        
        return peerNeighborIdx;
    }
    
    public void setCacheList(ArrayList<Cache> cacheList) {
        this.cacheList = cacheList;
    }
    
    public ArrayList<Cache> getCacheList() {
        return this.cacheList;
    }
    
    public boolean addCache(Cache peerCache) {
        boolean success = false;
        
        int cacheIdx = findCacheIdx(peerCache);
        if (cacheIdx == -1) {
            this.cacheList.add(peerCache);
            success = true;
        } else {
            ArrayList<PeerNode> cacheNodeList = this.cacheList.get(cacheIdx).getNodeList();
            ArrayList<PeerNode> newCacheNodeList = peerCache.getNodeList();
            
            int newCacheNodeLoop = 0;
            while (newCacheNodeLoop < newCacheNodeList.size()) {
                PeerNode newCacheNode = newCacheNodeList.get(cacheIdx);
                success = success || cacheNodeList.add(newCacheNode);
                newCacheNodeLoop++;
            }
        }
        
        return success;
    }
    
    public boolean removeCache(Cache remCache) {
        boolean success = false;
        
        int cacheIdx = findCacheIdx(remCache);
        if (cacheIdx != -1) {
            ArrayList<PeerNode> cacheNodeList = this.cacheList.get(cacheIdx).getNodeList();
            ArrayList<PeerNode> remCacheNodeList = remCache.getNodeList();
            
            int remCacheNodeLoop = 0;
            while (remCacheNodeLoop < remCacheNodeList.size()) {
                PeerNode remCacheNode = remCacheNodeList.get(remCacheNodeLoop);
                success = success || remCacheNodeList.remove(remCacheNode);
                remCacheNodeLoop++;
            }
            
            if (cacheNodeList.size() == 0) {
                this.cacheList.remove(cacheIdx);
                success = true;
            }
        }
        
        return success;
    }
    
    public int findCacheIdx(Cache peerCache) {
        int peerCacheIdx = -1;
        int loop = 0;
        Cache tempCache = null;
        
        while (loop < this.cacheList.size()) {
            tempCache = (Cache) this.cacheList.get(loop);
            
            if (tempCache.getResource().getResourceID().equals(peerCache.getResource().getResourceID())) {
                peerCacheIdx = loop;
                break;
            }
            
            loop++;
        }
        
        return peerCacheIdx;
    }
    
    public int findCacheIdxByKeyword(String resType, String resKeyword) {
        int peerCacheIdx = -1;
        int loop = 0;
        Cache tempCache = null;
        
        while (loop < this.cacheList.size()) {
            tempCache = (Cache) this.cacheList.get(loop);
            
            if ((tempCache.getResource().getResourceType().equals(resType)) && 
                    (tempCache.getResource().getResourceDetail().indexOf(resKeyword) != -1)) {
                peerCacheIdx = loop;
                break;
            }
            
            loop++;
        }
        
        return peerCacheIdx;
    }
    
    public boolean addRequestID(String reqID) {
        boolean success = false;
        
        int reqIDIdx = this.findRequestIDIdx(reqID);
        if (reqIDIdx == -1) {
            this.requestIDList.add(reqID);
            success = true;
        }
        
        return success;
    }
    
    public boolean removeRequestID(String reqID) {
        boolean success = false;
        
        int reqIDIdx = this.findRequestIDIdx(reqID);
        if (reqIDIdx != -1) {
            this.requestIDList.remove(reqIDIdx);
            success = true;
        }
        
        return success;
    }
    
    public int findRequestIDIdx(String reqID) {
        int reqIDIdx = -1;
        int loop = 0;
        
        while (loop < this.requestIDList.size()) {
            if (this.requestIDList.get(loop).equals(reqID)) {
                reqIDIdx = loop;
                break;
            }
            loop++;
        }
        
        return reqIDIdx;
    }
    
    public Document toXMLDoc() throws Exception {
        Document doc;
        XMLTools xt = new XMLTools();        
        doc = xt.db.newDocument();
        
        Element rootEle = doc.createElement("Peer");

        // Node
        Element peerNodeEle = doc.createElement("Peer:Node");
        
            // ID
            Element peerNodeIDEle = doc.createElement("Peer:Node:ID");
            Text peerNodeIDText = doc.createTextNode(this.node.getNodeID());
            peerNodeIDEle.appendChild(peerNodeIDText);
            peerNodeEle.appendChild(peerNodeIDEle);        

            // IPaddress
            Element peerNodeIPaddressEle = doc.createElement("Peer:Node:IPaddress");
            Text peerNodeIPaddressText = doc.createTextNode(this.node.getNodeIPaddress());
            peerNodeIPaddressEle.appendChild(peerNodeIPaddressText);
            peerNodeEle.appendChild(peerNodeIPaddressEle);        

            // Port
            Element peerNodePortEle = doc.createElement("Peer:Node:Port");
            Text peerNodePortText = doc.createTextNode(Integer.toString(this.node.getNodePort()));
            peerNodePortEle.appendChild(peerNodePortText);
            peerNodeEle.appendChild(peerNodePortEle);

        rootEle.appendChild(peerNodeEle);
        
        // NetworkID
        Element peerNetworkIDEle = doc.createElement("Peer:Network");
        Text peerNetworkIDText = doc.createTextNode(this.networkID);
        peerNetworkIDEle.appendChild(peerNetworkIDText);
        rootEle.appendChild(peerNetworkIDEle);
        
        // ResourceList
        Element peerResourceListEle = doc.createElement("Peer:ResourceList");
        
            int peerResourceLoop = 0;
            while (peerResourceLoop < this.resourceList.size()) {
                Resource peerResource = (Resource) this.resourceList.get(peerResourceLoop);
                
                Element peerResourceEle = doc.createElement("Peer:ResourceList:Resource");
                // ID
                Element peerResourceIDEle = doc.createElement("Peer:ResourceList:ID");
                Text peerResourceIDText = doc.createTextNode(peerResource.getResourceID());
                peerResourceIDEle.appendChild(peerResourceIDText);
                peerResourceEle.appendChild(peerResourceIDEle);        

                // Type
                Element peerResourceTypeEle = doc.createElement("Peer:ResourceList:Type");
                Text peerResourceTypeText = doc.createTextNode(peerResource.getResourceType());
                peerResourceTypeEle.appendChild(peerResourceTypeText);
                peerResourceEle.appendChild(peerResourceTypeEle);        

                // Detail
                Element peerResourceDetailEle = doc.createElement("Peer:ResourceList:Detail");
                Text peerResourceDetailText = doc.createTextNode(peerResource.getResourceDetail());
                peerResourceDetailEle.appendChild(peerResourceDetailText);
                peerResourceEle.appendChild(peerResourceDetailEle);  

                peerResourceListEle.appendChild(peerResourceEle);
                
                peerResourceLoop++;
            }
        
        rootEle.appendChild(peerResourceListEle);
        
        // NeighborList
        Element peerNeighborListEle = doc.createElement("Peer:NeighborList");
            
            int peerNeighborLoop = 0;
            while (peerNeighborLoop < this.neighborList.size()) {
                Neighbor peerNeighbor = (Neighbor) this.neighborList.get(peerNeighborLoop);
                
                Element peerNeighborEle = doc.createElement("Peer:NeighborList:Neighbor");
                
                    // Node
                    Element peerNeighborNodeEle = doc.createElement("Peer:NeighborList:Neighbor:Node");

                        // ID
                        Element peerNeighborNodeIDEle = doc.createElement("Peer:NeighborList:Neighbor:Node:ID");
                        Text peerNeighborNodeIDText = doc.createTextNode(peerNeighbor.getNode().getNodeID());
                        peerNeighborNodeIDEle.appendChild(peerNeighborNodeIDText);
                        peerNeighborNodeEle.appendChild(peerNeighborNodeIDEle);        

                        // IPaddress
                        Element peerNeighborNodeIPaddressEle = doc.createElement("Peer:NeighborList:Neighbor:Node:IPaddress");
                        Text peerNeighborNodeIPaddressText = doc.createTextNode(peerNeighbor.getNode().getNodeIPaddress());
                        peerNeighborNodeIPaddressEle.appendChild(peerNeighborNodeIPaddressText);
                        peerNeighborNodeEle.appendChild(peerNeighborNodeIPaddressEle);        

                        // Port
                        Element peerNeighborNodePortEle = doc.createElement("Peer:NeighborList:Neighbor:Node:Port");
                        Text peerNeighborNodePortText = doc.createTextNode(Integer.toString(peerNeighbor.getNode().getNodePort()));
                        peerNeighborNodePortEle.appendChild(peerNeighborNodePortText);
                        peerNeighborNodeEle.appendChild(peerNeighborNodePortEle);

                    peerNeighborEle.appendChild(peerNeighborNodeEle);

                    // Rank
                    Element peerNeighborRankEle = doc.createElement("Peer:NeighborList:Neighbor:Rank");
                    Text peerNeighborRankText = doc.createTextNode(Integer.toString(peerNeighbor.getRank()));
                    peerNeighborRankEle.appendChild(peerNeighborRankText);
                    peerNeighborEle.appendChild(peerNeighborRankEle);      
                
                peerNeighborListEle.appendChild(peerNeighborEle);
                
                peerNeighborLoop++;
            }
            
        rootEle.appendChild(peerNeighborListEle);
        
        // CacheList
        Element peerCacheListEle = doc.createElement("Peer:CacheList");
        
            int peerCacheLoop = 0;
            while (peerCacheLoop < this.cacheList.size()) {
                Cache peerCache = (Cache) this.cacheList.get(peerCacheLoop);
                
                Element peerCacheEle = doc.createElement("Peer:CacheList:Cache");
                
                    // Resource
                    Element peerCacheResourceEle = doc.createElement("Peer:CacheList:Cache:Resource");

                        // ID
                        Element peerCacheResourceIDEle = doc.createElement("Peer:CacheList:Cache:Resource:ID");
                        Text peerCacheResourceIDText = doc.createTextNode(peerCache.getResource().getResourceID());
                        peerCacheResourceIDEle.appendChild(peerCacheResourceIDText);
                        peerCacheResourceEle.appendChild(peerCacheResourceIDEle);        

                        // Type
                        Element peerCacheResourceTypeEle = doc.createElement("Peer:CacheList:Cache:Resource:Type");
                        Text peerCacheResourceTypeText = doc.createTextNode(peerCache.getResource().getResourceType());
                        peerCacheResourceTypeEle.appendChild(peerCacheResourceTypeText);
                        peerCacheResourceEle.appendChild(peerCacheResourceTypeEle);        

                        // Detail
                        Element peerCacheResourceDetailEle = doc.createElement("Peer:CacheList:Cache:Resource:Detail");
                        Text peerCacheResourceDetailText = doc.createTextNode(peerCache.getResource().getResourceDetail());
                        peerCacheResourceDetailEle.appendChild(peerCacheResourceDetailText);
                        peerCacheResourceEle.appendChild(peerCacheResourceDetailEle);        

                    peerCacheEle.appendChild(peerCacheResourceEle);

                    // NodeList
                    Element peerCacheNodeListEle = doc.createElement("Peer:CacheList:Cache:NodeList");

                    int peerCacheNodeLoop = 0;
                    PeerNode peerCacheNode = null;

                    while (peerCacheNodeLoop < peerCache.getNodeList().size()) {
                        Element peerCacheNodeEle = doc.createElement("Peer:CacheList:Cache:NodeList:Node");
                        peerCacheNode = (PeerNode) peerCache.getNodeList().get(peerCacheNodeLoop);

                            // ID
                            Element peerCacheNodeIDEle = doc.createElement("Peer:CacheList:Cache:NodeList:Node:ID");
                            Text peerCacheNodeIDText = doc.createTextNode(peerCacheNode.getNodeID());
                            peerCacheNodeIDEle.appendChild(peerCacheNodeIDText);
                            peerCacheNodeEle.appendChild(peerCacheNodeIDEle);        

                            // IPaddress
                            Element peerCacheNodeIPaddressEle = doc.createElement("Peer:CacheList:Cache:NodeList:Node:IPaddress");
                            Text peerCacheNodeIPaddressText = doc.createTextNode(peerCacheNode.getNodeIPaddress());
                            peerCacheNodeIPaddressEle.appendChild(peerCacheNodeIPaddressText);
                            peerCacheNodeEle.appendChild(peerCacheNodeIPaddressEle);        

                            // Port
                            Element peerCacheNodePortEle = doc.createElement("Peer:CacheList:Cache:NodeList:Node:Port");
                            Text peerCacheNodePortText = doc.createTextNode(Integer.toString(peerCacheNode.getNodePort()));
                            peerCacheNodePortEle.appendChild(peerCacheNodePortText);
                            peerCacheNodeEle.appendChild(peerCacheNodePortEle);        

                        peerCacheNodeListEle.appendChild(peerCacheNodeEle);
                        peerCacheNodeLoop++;
                    }
                
                    peerCacheEle.appendChild(peerCacheNodeListEle);
                    
                peerCacheListEle.appendChild(peerCacheEle);
                
                peerCacheLoop++;
            }
        
        rootEle.appendChild(peerCacheListEle);
        
        doc.appendChild(rootEle);                
        
        return doc;
    }    
    
    public String toXMLString() throws Exception {
        String result = null;
        
        XMLTools xt = new XMLTools();                
        result = xt.writeXMLString(this.toXMLDoc());
        
        return result;
    }
    
    public void toXMLFile(String fileName) throws Exception {
        // Prepare the DOM document for writing
        Source source = new DOMSource(this.toXMLDoc());

        // Prepare the output file
        File file = new File(fileName);
        Result result = new StreamResult(file);

        // Write the DOM document to the file
        Transformer xformer = TransformerFactory.newInstance().newTransformer();
        xformer.transform(source, result);
    }
    
    public Peer fromXMLDoc(Document dom) {
        Peer result = new Peer();
        
        Element rootEle = dom.getDocumentElement();
        
        if (rootEle.getTagName().equals("Peer")) {
            // Node
            PeerNode peerNode = new PeerNode();
            NodeList peerNodeIDList = rootEle.getElementsByTagName("Peer:Node:ID");
            String peerNodeIDText = peerNodeIDList.item(0).getFirstChild().getNodeValue();
            NodeList peerNodeIPaddressList = rootEle.getElementsByTagName("Peer:Node:IPaddress");
            String peerNodeIPaddressText = peerNodeIPaddressList.item(0).getFirstChild().getNodeValue();
            NodeList peerNodePortList = rootEle.getElementsByTagName("Peer:Node:Port");
            String peerNodePortText = peerNodePortList.item(0).getFirstChild().getNodeValue();
            peerNode.setNodeID(peerNodeIDText);
            peerNode.setNodeIPaddress(peerNodeIPaddressText);
            peerNode.setNodePort(Integer.valueOf(peerNodePortText));
            
            result.setNode(peerNode);
            
            // NetworkID
            NodeList peerNetworkIDList = rootEle.getElementsByTagName("Peer:Network");
            String peerNetworkIDText = peerNetworkIDList.item(0).getFirstChild().getNodeValue();
            
            result.setNetworkID(peerNetworkIDText);
            
            // ResourceList
            NodeList peerResourceListList = rootEle.getElementsByTagName("Peer:ResourceList");
            NodeList peerResourceList = rootEle.getElementsByTagName("Peer:ResourceList:Resource");

            int peerResourceLoop = 0;
            
            while (peerResourceLoop < peerResourceList.getLength()) {
                NodeList peerResourceListEle = peerResourceList.item(peerResourceLoop).getChildNodes();
                
                Resource peerResource = new Resource();
                
                String resourceIDText = peerResourceListEle.item(0).getFirstChild().getNodeValue();
                String resourceTypeText = peerResourceListEle.item(1).getFirstChild().getNodeValue();
                String resourceDetailText = peerResourceListEle.item(2).getFirstChild().getNodeValue();

                peerResource.setResourceID(resourceIDText);
                peerResource.setResourceType(resourceTypeText);
                peerResource.setResourceDetail(resourceDetailText);

                result.resourceList.add(peerResource);
                
                peerResourceLoop++;
            }
            
            // NeighborList
            NodeList peerNeighborListList = rootEle.getElementsByTagName("Peer:NeighborList");
            NodeList peerNeighborList = rootEle.getElementsByTagName("Peer:NeighborList:Neighbor");

            int peerNeighborLoop = 0;
            while (peerNeighborLoop < peerNeighborList.getLength()) {
                NodeList peerNeighborNodes = peerNeighborList.item(peerNeighborLoop).getChildNodes();
                
                Neighbor peerNeighbor = new Neighbor();
                PeerNode peerNeighborNode = new PeerNode();
                
                NodeList peerNeighborPeerNode = peerNeighborNodes.item(0).getChildNodes();
                
                String peerNeighborNodeIDText = peerNeighborPeerNode.item(0).getFirstChild().getNodeValue();
                String peerNeighborNodeIPaddressText = peerNeighborPeerNode.item(1).getFirstChild().getNodeValue();
                String peerNeighborNodePortText = peerNeighborPeerNode.item(2).getFirstChild().getNodeValue();

                peerNeighborNode.setNodeID(peerNeighborNodeIDText);
                peerNeighborNode.setNodeIPaddress(peerNeighborNodeIPaddressText);
                peerNeighborNode.setNodePort(Integer.valueOf(peerNeighborNodePortText));

                NodeList peerNeighborRankList = rootEle.getElementsByTagName("Peer:NeighborList:Neighbor:Rank");
                String peerNeighborRankText = peerNeighborNodes.item(1).getFirstChild().getNodeValue();

                peerNeighbor.setNode(peerNeighborNode);
                peerNeighbor.setRank(Integer.valueOf(peerNeighborRankText));
                
                result.neighborList.add(peerNeighbor);
                
                peerNeighborLoop++;
            }
            
            // CacheList
            NodeList peerCacheListList = rootEle.getElementsByTagName("Peer:CacheList");
            NodeList peerCacheList = rootEle.getElementsByTagName("Peer:CacheList:Cache");

            int peerCacheLoop = 0;
            while (peerCacheLoop < peerCacheList.getLength()) {
                NodeList peerCacheListNodes = peerCacheList.item(peerCacheLoop).getChildNodes();
                
                Cache peerCache = new Cache();
                
                // Resource
                NodeList peerCacheResourceList = rootEle.getElementsByTagName("Peer:CacheList:Cache:Resource");

                Resource peerCacheResource = new Resource();

                NodeList peerCacheResourceIDList = rootEle.getElementsByTagName("Peer:CacheList:Cache:Resource:ID");
                String peerCacheResourceIDText = peerCacheResourceIDList.item(peerCacheLoop).getFirstChild().getNodeValue();
                NodeList peerCacheResourceTypeList = rootEle.getElementsByTagName("Peer:CacheList:Cache:Resource:Type");
                String peerCacheResourceTypeText = peerCacheResourceTypeList.item(peerCacheLoop).getFirstChild().getNodeValue();
                NodeList peerCacheResourceDetailList = rootEle.getElementsByTagName("Peer:CacheList:Cache:Resource:Detail");
                String peerCacheResourceDetailText = peerCacheResourceDetailList.item(peerCacheLoop).getFirstChild().getNodeValue();
                peerCacheResource.setResourceID(peerCacheResourceIDText);
                peerCacheResource.setResourceType(peerCacheResourceTypeText);
                peerCacheResource.setResourceDetail(peerCacheResourceDetailText);
                peerCache.setResource(peerCacheResource);
                
                // NodeList
                NodeList peerCacheNodeListList = rootEle.getElementsByTagName("Peer:CacheList:Cache:NodeList");
                NodeList peerCacheNodeList = peerCacheNodeListList.item(peerCacheLoop).getChildNodes();

                int peerCacheNodeLoop = 0;
                while (peerCacheNodeLoop < peerCacheNodeList.getLength()) {
                    NodeList peerCacheNodeListEle = peerCacheNodeList.item(peerCacheNodeLoop).getChildNodes();

                    PeerNode peerCacheNode = new PeerNode();

                    String peerCacheNodeIDText = peerCacheNodeListEle.item(0).getFirstChild().getNodeValue();
                    String peerCacheNodeIPaddressText = peerCacheNodeListEle.item(1).getFirstChild().getNodeValue();
                    String peerCacheNodePortText = peerCacheNodeListEle.item(2).getFirstChild().getNodeValue();

                    peerCacheNode.setNodeID(peerCacheNodeIDText);
                    peerCacheNode.setNodeIPaddress(peerCacheNodeIPaddressText);
                    peerCacheNode.setNodePort(Integer.valueOf(peerCacheNodePortText));

                    peerCache.addNode(peerCacheNode);

                    peerCacheNodeLoop++;
                }

                result.cacheList.add(peerCache);
                
                peerCacheLoop++;
            }
        }
                
        return result;
    }
    
    public Peer fromXMLString(String data) throws Exception {
        Document dom = null;
        XMLTools xt = new XMLTools();
        Peer result = null;
        
        // Parse the XML stream input to Document type
        dom = xt.db.parse(new InputSource(new StringReader(data)));
        
        result = fromXMLDoc(dom);
        
        return result;
    }
    
    public Peer fromXMLFile(String fileName) throws Exception {
        Document dom = null;
        File file = null;
        Peer result = null;
        XMLTools xt = new XMLTools();
        
        // Parse the XML stream input to Document type
        file = new File(fileName);
        dom = xt.db.parse(file);
        
        result = fromXMLDoc(dom);
        
        return result;
    }
    
//    public static void main(String[] args) throws Exception {
//        PeerNode n1 = new PeerNode("192.168.0.1", 9090);
//        PeerNode n2 = new PeerNode("192.168.0.2", 9090);
//        PeerNode n3 = new PeerNode("192.168.0.3", 9090);
//        
//        Neighbor nb1 = new Neighbor(n1,1);
//        Neighbor nb2 = new Neighbor(n2,1);
//        Neighbor nb3 = new Neighbor(n3,1);
//        
//        Resource r1 = new Resource("file", "./1.res");
//        Resource r2 = new Resource("file", "./2.res");
//        
//        Cache c1 = new Cache();
//        c1.setResource(r1);
//        c1.addNode(n2);
//        c1.addNode(n3);
//        
//        Cache c2 = new Cache();
//        c2.setResource(r2);
//        c2.addNode(n3);
//        
//        Peer p1 = new Peer(n1);
//        p1.addResource(r1);
//        p1.addResource(r2);
//        
//        p1.addNeighborNode(n2);
//        p1.addNeighborNode(n3);
//        
//        p1.addCache(c1);
//        p1.addCache(c2);
//        
//        p1.toXMLFile("p1.xml");
//        
//        Peer p2 = new Peer();
//        p2 = p2.fromXMLFile("./conf/peer1.xml");
//        
//        p2.toXMLFile("./conf/peer2.xml");
//    }
}
